<?php
/*******************************************************************************
 * $Date:: Jan 9, 2011 12:31:05 AM                                              $
 * $Revision:                                                                  $
 * $Author:: Tuan Duong                                                        $
 * $Comment::                                                                  $
 ******************************************************************************/ 
/**
 * Description here...
 * 
 * @package Lua
 * @subpackage ##Subpackage##
 * @author Tuan Duong <bacduong[at]gmail[dot]com>
 * @version 
 */

class Lua_Grid
{
    /**
     * @var Zend_Paginator
     */
    private $paginator = null;

    /**
     * @var array of BKH_Grid_Column_Abstract
     */
    private $gridColumns = array();

    /**
     * @var array
     */
    private $gridData = array();

    /**
     * @var int
     */
    private $itemPerPage = 20;

    /**
     * @var int
     */
    private $currentPage = 1;

    /**
     * @var Zend_View
     */
    private $view;

    /**
     * @var array
     */
    private $options;

    /**
     * @var array
     */
    private $params;
    /**
     * @var string
     */
    private $templateDir = 'grid';

    /**
     * @var string
     */
    private $paginatorTemplate = '_paginator.phtml';

    private $nowrap = false;

    private $renderRowId = false;

    /**
     * Constructor of Grid
     * @param mixed $adapter
     * @param  $options
     * @return void
     */
    public function __construct($adapter, array $options = null)
    {
        $this->options = array(
            'cellpadding' => 0,
            'cellspacing' => 0,
            'border' => 0,
            'width' => '100%',
            'cssRowEven' => 'row0',
            'cssRowOdd' => 'row1',
            'cssClass' => 'grid',
        );

        $this->options = array_merge($this->options, $options);
        $this->paginator = Lua_Paginator::factory($adapter);
    }
    
    public function deploy()
    {
        $this->paginator->setItemCountPerPage($this->itemPerPage);
        $this->paginator->setCurrentPageNumber($this->currentPage);
        $this->gridData = $this->paginator->getItemsByPage($this->currentPage)->toArray();

        // @todo: refactor grid render and remove cheat here
        $baseIndex = ($this->paginator->getCurrentPageNumber() - 1)* $this->itemPerPage + 1;
        $length = count($this->gridData);
        for ($i = 0; $i < $length; $i++) {
            $this->gridData[$i]['_index'] = $baseIndex + $i;
        }
    }
    
    public function render($part = '')
    {
        if (0 == count($this->gridData)) {
            $this->deploy();
        }
        if ('' == $part) {
            $gridHtml = "<table class='" . $this->options['cssClass'] . "'";
            $gridHtml .= 'cellspacing="' . $this->cellspacing . '" ';
            $gridHtml .= 'cellpadding="' . $this->cellpadding . '" ';
            $gridHtml .= 'border="' . $this->border . '" ';
            $gridHtml .= 'width="' . $this->width . '" ';
            $gridHtml .= ">\n";
            $gridHtml .= $this->_renderHeader();
            $gridHtml .= $this->_renderGrid();
            $gridHtml .= $this->_renderPaginator();
            $gridHtml .= "</table>";
        } else {
            $method = '_render' . ucfirst($part);
            $gridHtml = $this->$method();
        }
        return $gridHtml;
    }

    protected function _renderPaginator()
    {
        $html = "  <tfoot>\n";
        $html .= "  <tr>\n";
        $html .= "    <td colspan = \"" . count($this->gridColumns) . "\">\n";
        $html .= $this->view->paginationControl($this->paginator, 'Sliding', $this->templateDir . '/' . $this->paginatorTemplate, array('params' => $this->params));
        $html .= "    </td>\n";
        $html .= "  </tr>\n";
        $html .= "  </tfoot>\n";
        return $html;
    }
    protected function _renderHeader()
    {
        $html = "  <thead>\n";
        $html .= "  <tr>\n";
        foreach ($this->gridColumns as $key => $columns)
        {
            $html .= $columns->renderHeader($this->view, $this->nowrap);        
        }
        $html .= "  </tr>\n";
        $html .= "  </thead>\n";
        return $html;
    }
    
    protected function _renderGrid()
    {
        $gridHtml = "<tbody>\n";
        $gridHtml .= $this->_renderGridContent();
        $gridHtml .= "</tbody>\n";
        return $gridHtml;
    }
    
    protected function _renderGridContent()
    {
        $contentHtml = '';
        foreach ($this->gridData as $row) {
            $rowHtml = '  <tr class="' . $this->view->cycle(array($this->cssRowEven, $this->cssRowOdd))->next() . '">' . "\n";
            foreach ($this->gridColumns as $column) {
                if (array_key_exists($column->key, $row)) {
                    $rowHtml .= $column->renderCell($row[$column->key], $row);
                } else {
                    $rowHtml .= $column->renderCell('', $row);
                }
            }
            $rowHtml .= "  </tr>\n";
            $contentHtml .= $rowHtml;
        }
        return $contentHtml;
    }

    /**
     * Build grid columns
     * @param Lua_Grid_Column_Abstract|mixed $fields
     * @param unknown_type $autoBind
     */
    public function buildColumns($fields, $autoBind = true)
    {
        foreach ($fields as $field) {
            if ($field instanceof Lua_Grid_Column_Abstract) {
                $this->gridColumns[] = $field;
            } else {
                if (is_array($field)) {
                    $key = $field['key'];
                    $options = $field;
                } else {
                    $key = $field;
                    $options = array();
                }

                if ('time' == substr($key, -4)) {
                    $this->gridColumns[] = new Lua_Grid_Column_Date($key, $options);
                } else {
                    $this->gridColumns[] = new Lua_Grid_Column_Value($key, $options);
                }
            }
        }
    }
    
    public function setView(Zend_View_Abstract $view) 
    {
        $this->view = $view;
    }
    
    public function __get($key)
    {
        if (isset($this->options[$key])) {
            return $this->options[$key];
        } else {
            return "";
        }
    }
    
	/**
     * @param int $itemPerPage
     */
    public function setItemPerPage($itemPerPage)
    {
        $this->itemPerPage = $itemPerPage;
    }

    /**
     * @param array $params
     */
    public function setParams(array $params = array())
    {
        $this->params = $params;
        if (isset($this->params['page'])) {
            $this->currentPage = $this->params['page'];
        }
        
        if (isset($this->params['limit'])) {
            $this->itemPerPage = $this->params['limit'];
        } else {
            $this->params['limit'] = $this->itemPerPage;
        }
    }
    
}